// #include <iostream>
// #include <vector>
// using namespace std;
// const int N = 1000000000;
// vector<pair<int, int>> a(1005);
// int main() {
//     int n;
//     cin >> n;
//     while(n--) {
//         int x1, y1, x2, y2;
//         cin >> x1 >> y1 >> x2 >> y2;
//         x1 += N;
//         x2 += N;
//         y1 += N;
//         y2 += N;

//     }
// }


#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

typedef long long ll;

struct Edge {
    ll x1, x2;  // x坐标范围
    ll y;       // y坐标
    int type;   // 类型：1表示矩形的下边，-1表示上边
};

// 比较函数：按y坐标排序
bool cmp(const Edge& a, const Edge& b) {
    return a.y < b.y;
}

int main() {
    int n;
    cin >> n;
    
    vector<Edge> edges;
    vector<ll> all_x;  // 用于离散化的所有x坐标
    
    // 读取输入并构建边
    for (int i = 0; i < n; i++) {
        ll x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        
        // 确保x1 < x2, y1 < y2（题目给的是左上角和右下角）
        if (x1 > x2) swap(x1, x2);
        if (y1 > y2) swap(y1, y2);
        
        // 添加矩形的两条边
        edges.push_back({x1, x2, y1, 1});  // 下边
        edges.push_back({x1, x2, y2, -1}); // 上边
        
        // 收集x坐标用于离散化
        all_x.push_back(x1);
        all_x.push_back(x2);
    }
    
    // 离散化x坐标
    sort(all_x.begin(), all_x.end());
    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());
    
    // 创建离散化映射
    map<ll, int> x_to_index;
    for (int i = 0; i < all_x.size(); i++) {
        x_to_index[all_x[i]] = i;
    }
    
    // 按y坐标排序所有边
    sort(edges.begin(), edges.end(), cmp);
    
    // 线段树数组（这里用数组模拟，记录每个离散区间的覆盖次数）
    vector<int> cover(all_x.size() - 1, 0);
    
    ll total_area = 0;
    ll last_y = edges[0].y;
    
    // 扫描所有边
    for (const Edge& edge : edges) {
        // 计算当前扫描线与上一条扫描线之间的面积
        if (edge.y != last_y) {
            // 计算当前被覆盖的总宽度
            ll covered_width = 0;
            for (int i = 0; i < all_x.size() - 1; i++) {
                if (cover[i] > 0) {
                    covered_width += all_x[i + 1] - all_x[i];
                }
            }
            
            // 累加面积
            total_area += covered_width * (edge.y - last_y);
            last_y = edge.y;
        }
        
        // 更新覆盖状态
        int idx1 = x_to_index[edge.x1];
        int idx2 = x_to_index[edge.x2];
        
        for (int i = idx1; i < idx2; i++) {
            cover[i] += edge.type;
        }
    }
    
    cout << total_area << endl;
    
    return 0;
}